#pragma once

#include <QObject>
#include <QDateTime>
#include <QHash>
#include <QList>
#include <QString>
#include <memory>
#include "caller_protocol.h"
#include "infrastructure/io/tcp_socket_server.h"
#include "kernel/interfaces/ILogger.h"

namespace application {
namespace caller {

struct CallerRuntimeInfo {
    int callerNum{0};
    QString taskName;
    bool isOnline{false};
    QDateTime lastTriggerTime;
};

/**
 * @brief 呼叫器管理器
 * @details 管理所有呼叫器连接和按钮映射
 */
class CallerManager : public QObject {
    Q_OBJECT

public:
    explicit CallerManager(std::shared_ptr<kernel::ILogger> logger = nullptr, QObject* parent = nullptr);
    ~CallerManager() = default;

    /**
     * @brief 初始化连接(开放TCP端口)
     * @param port 监听端口，默认8080
     */
    void initConnection(quint16 port = 8080);

    /**
     * @brief 创建呼叫器按钮到任务的映射
     * @param callerNum 呼叫器编号
     * @param taskName 任务名称
     */
    void createTaskConnection(int callerNum, const QString& taskName);

    /**
     * @brief 移除呼叫器映射
     */
    void removeTaskConnection(int callerNum);

    /**
     * @brief 获取所有呼叫器映射
     */
    QHash<int, QString> getAllCallerMappings() const { return m_callerNumToTaskName; }
    QList<CallerRuntimeInfo> getCallerRuntimeInfos() const;
    void sendTaskResult(const CallerMessage& callerMsg, bool success);

signals:
    /**
     * @brief 呼叫器按钮被按下信号
     */
    void buttonPressed(CallerMessage msg);
    void callerRuntimeInfoChanged();

private slots:
    void slot_incomingNewConnection(qint64 socketDescriptor, const QString& ip, quint16 port);
    void slot_disconnected();

private:
    void responseLogin(CallerProtocol* protocol);
    void responseAuthentication(QByteArray& receiveData, CallerProtocol* protocol);
    void responseButtonPressed(QByteArray& receiveData, CallerProtocol* protocol);
    bool markCallerOnline(int callerNum, CallerProtocol* protocol);
    bool markCallerOffline(CallerProtocol* protocol);
    CallerRuntimeInfo& ensureRuntimeInfo(int callerNum);
    void notifyRuntimeChanged();

private:
    infrastructure::io::TcpSocketServer* m_tcpSocketServer = nullptr;
    QHash<int, QString> m_callerNumToTaskName;  // 呼叫器编号 -> 任务名称映射
    QHash<int, CallerRuntimeInfo> m_runtimeInfos;
    QHash<CallerProtocol*, int> m_protocolToCaller;
    QHash<infrastructure::io::TcpSocketClient*, CallerProtocol*> m_clientToProtocol;
    std::shared_ptr<kernel::ILogger> m_logger;
};

} // namespace caller
} // namespace application
